package com.wetao.module_pen.fragment;

import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;

import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.Settings;

import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;


import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.tstudy.blepenlib.BlePenManager;
import com.tstudy.blepenlib.BlePenStreamManager;
import com.tstudy.blepenlib.data.BleDevice;
import com.tstudy.blepenlib.data.CoordinateInfo;
import com.wetao.lib_common.Constants;
import com.wetao.lib_common.base.BaseListResponse;
import com.wetao.lib_common.base.BaseNestingLazyFragment;
import com.wetao.lib_common.base.BaseResponse;
import com.wetao.lib_common.bean.request.StudentExamGridInfoReq;
import com.wetao.lib_common.bean.request.StudentExamGridInfoReq_vo;
import com.wetao.lib_common.bean.response.CheckStudentMacResp;

import com.wetao.lib_common.bean.response.StudentExamGridInfoResp;
import com.wetao.lib_common.bean.response.StudentExamGridInfoResp_grids;
import com.wetao.lib_common.bean.vo.PictureMore;
import com.wetao.lib_common.compare.ComparePenOffLinePage;
import com.wetao.lib_common.finalParam.GridSourceContentType;
import com.wetao.lib_common.finalParam.IsAnswerSheetType;
import com.wetao.lib_common.finalParam.PageSourceType;
import com.wetao.lib_common.greendao.DBUtils;
import com.wetao.lib_common.greendao.model.PenOffLineGridInfo;
import com.wetao.lib_common.greendao.model.PenOffLineGridInfoChild;
import com.wetao.lib_common.tsdBlePen.TsdPenUtil;
import com.wetao.lib_common.tsdBlePen.TsdService;
import com.wetao.lib_common.utils.BitmapUtil;
import com.wetao.lib_common.utils.ComUtil;
import com.wetao.lib_common.utils.CompareUtil;
import com.wetao.lib_common.utils.DialogXUtil;
import com.wetao.lib_common.utils.FileUtils;
import com.wetao.lib_common.utils.JsonUtils;
import com.wetao.lib_common.utils.LogUtils;
import com.wetao.lib_common.utils.MyDividerItemDecoration;
import com.wetao.lib_common.utils.SPUtils;
import com.wetao.lib_common.utils.StringUtil;
import com.wetao.lib_common.utils.WrapContentLinearLayoutManager;
import com.wetao.lib_common.view.graffiti.GraffitiOnTouchGestureListener;
import com.wetao.lib_common.view.graffiti.GraffitiTouchDetector;
import com.wetao.lib_common.view.graffiti.GraffitiView;
import com.wetao.lib_common.view.graffiti.IGraffitiTouchDetector;
import com.wetao.module_pen.PenMainActivity;
import com.wetao.module_pen.R;
import com.wetao.module_pen.R2;
import com.wetao.module_pen.adapter.PenMainListAdapter;
import com.wetao.module_pen.contract.PenConnectFragmentCon;
import com.wetao.module_pen.presenter.PenConnectFragmentPre;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


public class PenConnectFragment extends BaseNestingLazyFragment<PenConnectFragmentCon.View, PenConnectFragmentPre> implements PenConnectFragmentCon.View  {

    private static final String ARG_PARAM1 = "param1";
    private String mParam1;
    private OnFragmentInteractionListener mListener;

    private int mErr_code = 0;
    @BindView(R2.id.tv_err)
    TextView tv_err;
    @BindView(R2.id.ll_link_status_parent)
    LinearLayout ll_link_status_parent;
    @BindView(R2.id.iv_refresh)
    ImageView iv_refresh;
    private Animation scanAnim;

    @BindView(R2.id.ll_pen_info)
    LinearLayout ll_pen_info;
    @BindView(R2.id.tv_no_find)
    TextView tv_no_find;
    @BindView(R2.id.iv_refresh_big)
    ImageView iv_refresh_big;
    @BindView(R2.id.tv_refrsh_data)
    TextView tv_refrsh_data;
    @BindView(R2.id.tv_pen_mac)
    TextView tv_pen_mac;
    @BindView(R2.id.iv_pen_dianliang)
    ImageView iv_pen_dianliang;
    @BindView(R2.id.tv_pen_dianliang)
    TextView tv_pen_dianliang;


    @BindView(R2.id.rv_no_link)
    RecyclerView rv_no_link;
    private PenMainListAdapter mPenMainListAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private MyDividerItemDecoration mDividerItemDecoration;

    private float mTemp_x = 0f; //暂存转换后的坐标
    private float mTemp_y = 0f;
    private ConcurrentLinkedQueue<CoordinateInfo> mOffLineDots = new ConcurrentLinkedQueue();
    private StudentExamGridInfoReq mOffLineReq = new StudentExamGridInfoReq(2);
    private List<StudentExamGridInfoResp> mStudentExamGridInfo = null;
    private CoordinateInfo mCurDot;//当前正在绘制的点；
    private PenOffLineGridInfo mCurGrid; //当前点绘制在那张图片上
    private PenOffLineGridInfo mCurGrid_isMore_endnull; //一页多课时时，第一笔点击的是格子区域，最后一笔点击的是非格子区域，显示不了这个可是
    private int mPic_w;
    private int mPic_h;
    private int mMinDotNum =600; //切换线程前最少绘制的点，超过这个数，遇到up,切换线程，需要切换图片，切换线程。
    private int mMaxDotNum = 1000; //切换线程前最多绘制的点
    private int mCurDotNum = 0; //记录当前线程绘制的点
    private String mPicFilePath_b;
    private String mPicFilePath_f;
    private String mPicFilePath_c;
    private Bitmap mDoodle_b = null;
    private Bitmap mDoodle_f = null;
    private boolean mIsLoadImg_b_end = false;
    private boolean mIsLoadImg_f_end = false;

    @BindView(R2.id.fl_doodle)
    FrameLayout fl_doodle;

    private GraffitiView mGraffitiView;
    private GraffitiOnTouchGestureListener mGraffitiTouchGestureListener;
    private Bitmap mSmall_bitmap = null;

    private Disposable disposable;
    private int mMemoryByteNum;




    public PenConnectFragment() {
    }

    public static PenConnectFragment newInstance(/*String param1*/) {
        PenConnectFragment fragment = new PenConnectFragment();
        Bundle args = new Bundle();
        //args.putString(ARG_PARAM1, param1);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getLayoutId() {
        return R.layout.pen_connect_fragment;
    }

    @Override
    public PenConnectFragmentPre createPresenter() {
        return new PenConnectFragmentPre(mContext);
    }

    @Override
    public PenConnectFragmentCon.View createView() {
        return this;
    }

    @Override
    public void checkStudentMacResult(BaseResponse<CheckStudentMacResp> response, BleDevice posBle) {

        String lastMack_2 = SPUtils.getInstance().getString(Constants.USER_PEN_MAC);
        CheckStudentMacResp resp = response.getData();
        if(resp != null) {
            if(!StringUtil.isEmpty(resp.getLastPenStudentName())
                    || !StringUtil.isEmpty(resp.getLastPenTeacherName())) {
                //这只笔已经绑定了其他账号
                //弹框 谁连接了
                DialogXUtil.customDialogShow("当前智能笔已绑定"
                        + ((!StringUtil.isEmpty(resp.getLastPenStudentName()))
                        ? (resp.getLastPenStudentName() + "同学")
                        : (resp.getLastPenTeacherName() + "老师"))
                        + "，请连接未绑定的智能笔！",
                        "", "好的", true,  new DialogXUtil.OnDialogXListen() {
                    @Override
                    public void onListenDialogOk() {
                    }
                    @Override
                    public void onListenDialogCancel() {
                    }
                    @Override
                    public void onListenDialogClose() {
                    }
                });
            } else  {
                if(StringUtil.isEmpty(lastMack_2)) {
                    //这个账号从来没有连过笔
                    //直接连接
                    penConnect(posBle);
                } else {
                    //这个账号连接过笔，更换笔
                    //弹框 更换笔
                    DialogXUtil.customDialogShow("你正在连接新的智能笔，\r\n确定要更换智能笔吗？",  new DialogXUtil.OnDialogXListen() {
                        @Override
                        public void onListenDialogOk() {
                            penConnect(posBle);
                        }
                        @Override
                        public void onListenDialogCancel() {
                        }
                        @Override
                        public void onListenDialogClose() {
                        }
                    });
                }
            }

        } else {
            LogUtils.e("后台返回数据为null");
        }

    }

    @Override
    public void checkStudentMacFailed() {
    }

    @Override
    public void studentConfirmConnectResult(BaseResponse<CheckStudentMacResp> response, BleDevice posBle) {
        CheckStudentMacResp resp = response.getData();
        SPUtils.getInstance().put(Constants.USER_PEN_MAC, posBle.getMac());

    }

    @Override
    public void studentConfirmConnectFailed() {

    }

    @Override
    public void studentExamGridInfoResult(BaseListResponse<StudentExamGridInfoResp> response) {
        if(mStudentExamGridInfo == null) {
            mStudentExamGridInfo = response.getData();
            if (mStudentExamGridInfo != null && mStudentExamGridInfo.size() > 0) {
                gridInfoToDb(mStudentExamGridInfo);
                mCurDot = mOffLineDots.poll();
                changePic();
            } else {
                if (DialogXUtil.isShowProgressDialog()) {
                    DialogXUtil.hideProgressDialog();
                    if(mListener != null) {
                        mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
                    }
                }
            }
        }
    }

    @Override
    public void studentExamGridInfoFailed() {
        if(DialogXUtil.isShowProgressDialog()) {
            DialogXUtil.hideProgressDialog();
            if(mListener != null) {
                mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
            }
        }
    }

    @Override
    public void studentExamCommitPenDataResult(BaseResponse response) {

    }

    @Override
    public void studentExamCommitPenDataFailed() {

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        LogUtils.e("onAttach");
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        LogUtils.e("onDetach");
        mListener.on_ct_finishPre();
        mListener = null;
        if(scanAnim != null) {
            scanAnim.cancel();
            scanAnim = null;
        }
    }

    @Override
    public void onDestroyView() {
        if(iv_refresh != null) {
            iv_refresh.clearAnimation();
        }
        if(DialogXUtil.isShowProgressDialog()) {
            DialogXUtil.hideProgressDialog();
        }
        rxjava_disposable();
        super.onDestroyView();
        /*if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }*/
    }

    @Override
    public void onFragmentFirst() {
        super.onFragmentFirst();
        /*if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }*/
    }

    @Override
    public void onFragmentVisble() {
        super.onFragmentVisble();
    }

    @Override
    public void onFragmentInVisible() {
        super.onFragmentInVisible();
    }

    @Override
    public void init(View rootView) {
        if (getArguments() != null) {
            //mParam1 = getArguments().getString(ARG_PARAM1);
        }

        scanAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate);
        scanAnim.setInterpolator(new LinearInterpolator());
        mSmall_bitmap = BitmapUtil.ReadBitmapById_4444(this.getActivity(), R.drawable.doodle_bk);

        initRecyclerView();

        if(mListener != null) {
            boolean isConnect = mListener.on_ct_getmBleDevice() != null;
            if(isConnect) {
                setRealtimeMode();//为了在作答界面，自动连接蓝牙，有离线数据的情况
                refreshShowView(isConnect);
            } else {
                mListener.on_ct_startScan();
            }
        }
    }

    @OnClick({R2.id.tv_err,
            R2.id.ll_link_status_parent,
            R2.id.ll_pen_duankai,
            R2.id.iv_refresh_big
    })
    public void onViewClick(View v) {
        int id = v.getId();
        if(id == R.id.tv_err) {
            if(mErr_code == TsdService.ERR_TSD_GPS) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivityForResult(intent, PenMainActivity.REQUEST_CODE_OPEN_GPS);
            } else if(mErr_code == TsdService.ERR_TSD_BT_NO_OPEN) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, PenMainActivity.REQUEST_OPEN_BT_CODE);
            }
        } else if(id == R.id.ll_link_status_parent) {
            if(mListener != null) {
                if(mListener.on_ct_isScaning()) {
                    mListener.on_ct_stopScan();
                } else {
                    mListener.on_ct_startScan();
                }
            }
        } else if(id == R.id.ll_pen_duankai) {
            BleDevice bleDevice = mListener != null ? mListener.on_ct_getmBleDevice() : null;
            if(bleDevice != null) {
                if (BlePenStreamManager.getInstance().isConnected(bleDevice)) {
                    //如果当前设备已连接，断开连接。
                    BlePenStreamManager.getInstance().disconnect(bleDevice);
                }
            }
        } else if(id == R.id.iv_refresh_big) {
            setRealtimeMode();
        }
    }

    private void initRecyclerView() {
        mLayoutManager = new WrapContentLinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
        mPenMainListAdapter = new PenMainListAdapter();

        rv_no_link.setLayoutManager(mLayoutManager);
        mDividerItemDecoration = new MyDividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL, R.drawable.divider_mileage_voice_class);
        rv_no_link.addItemDecoration(mDividerItemDecoration);
        rv_no_link.setItemAnimator( new DefaultItemAnimator());
        rv_no_link.setAdapter(mPenMainListAdapter);
        String lastMack = SPUtils.getInstance().getString(Constants.USER_PEN_MAC);

        mPenMainListAdapter.setmLastDevMac(lastMack);

        ((PenMainListAdapter)mPenMainListAdapter).setOnItemClickListener(new PenMainListAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                LogUtils.i("onItemClick--" + position);
                BleDevice bleDevice = mPenMainListAdapter.getBleDevice(position);
                String lastMack_2 = SPUtils.getInstance().getString(Constants.USER_PEN_MAC);
                String studentId = SPUtils.getInstance().getString(Constants.USER_ID_KEY);
                if(!StringUtil.isEmpty(lastMack_2) && lastMack_2.equals(bleDevice.getMac())) {
                    //这个账号上次连接的就是这个笔
                    penConnect(bleDevice);
                } else{
                    getPresenter().checkStudentMac(ComUtil.getHashmapByStr(
                            new String[]{"penMac", "penType", "studentId"},
                            new String[]{bleDevice.getMac(), "2", studentId})
                            , false, false, bleDevice);
                }

            }
        });
    }

    private void penConnect(BleDevice bleDevice) {
        if (!BlePenStreamManager.getInstance().isConnected(bleDevice)) {
            if(mListener != null) {
                DialogXUtil.waitDialogShow("正在连接中...");
                mListener.on_ct_penConnect(bleDevice);
            }
        }
    }

    private void refreshShowView(boolean isConneced) {
        mListener.on_ct_setIsConnect(isConneced);
        if(isConneced) {
            tv_err.setVisibility(View.GONE);
            ll_link_status_parent.setVisibility(View.GONE);
            iv_refresh.setVisibility(View.GONE);
            rv_no_link.setVisibility(View.GONE);

            ll_pen_info.setVisibility(View.VISIBLE);
            tv_no_find.setVisibility(View.VISIBLE);
            iv_refresh_big.setVisibility(View.VISIBLE);
            tv_refrsh_data.setVisibility(View.VISIBLE);

            BlePenStreamManager.getInstance().getPenInfo();
            if(mListener != null && mListener.on_ct_getmBleDevice() != null) {
                tv_pen_mac.setText("MAC:" + mListener.on_ct_getmBleDevice().getMac());
            }

            fl_doodle.setVisibility(View.INVISIBLE);
        } else {
            //tv_err.setVisibility(View.VISIBLE);
            ll_link_status_parent.setVisibility(View.VISIBLE);
            iv_refresh.setVisibility(View.VISIBLE);
            rv_no_link.setVisibility(View.VISIBLE);

            ll_pen_info.setVisibility(View.GONE);
            tv_no_find.setVisibility(View.GONE);
            iv_refresh_big.setVisibility(View.GONE);
            tv_refrsh_data.setVisibility(View.GONE);

            fl_doodle.setVisibility(View.GONE);
        }
    }

    private void gridInfoToDb(List<StudentExamGridInfoResp> resp) {
        for(int i = 0; i < resp.size(); i++) {
            StudentExamGridInfoResp item = resp.get(i);
            if(item.getIsAnswerSheet().intValue() != IsAnswerSheetType.SHEET_TYPE_2) {
                //不是点阵教辅、图谱、未入库的点码，则不入库。
                continue;
            }
            if(item.getId() == null || item.getExamId() == null) {
                //图谱中不是图谱点阵作答的，不入库
                //未入库的点码，不入库。
                LogUtils.e("m1: item.getId() == null || item.getExamId() == null");
                continue;
            }
            if(item.getGrids() == null || item.getGrids().size() == 0) {
                //挂了图片，但是没有挂格子的不入库
                LogUtils.e("m1: 格子为null的丢弃");
                continue;
            }
            PenOffLineGridInfo info = DBUtils.getInstance(this.getActivity()).getPenOffLineGridInfoByPicId(item.getId());
            if(info == null) {
                boolean isMore = false; //这一页是否有多个课时
                for(int j = 0; j < resp.size(); j++) {
                    if(i != j
                            && item.getPageserial() != null
                            && item.getPageserial().equals(resp.get(j).getPageserial())) {
                        isMore = true;
                        break;
                    }
                }

                PictureMore pictureMore = new PictureMore();
                if(isMore) {
                    List<StudentExamGridInfoResp_grids> grids = item.getGrids();
                    for(StudentExamGridInfoResp_grids g : grids) {
                        pictureMore.setTemp1(g.getStartX(), g.getStartY(), g.getEndX(), g.getEndY(), g.getBigPicWidth(), g.getBigPicHeight());
                    }

                    LogUtils.e("计算格子设置范围步骤一：" + pictureMore.toString());
                    pictureMore.setTemp2(item.getWidth(), item.getHeight());
                    LogUtils.e("计算格子设置范围步骤二：" + pictureMore.toString());
                }
                //插入页信息
                Long penOffLineGridInfoId = DBUtils.getInstance(this.getActivity()).insertPenOffLineGridInfo(
                        new PenOffLineGridInfo(null, item.getId(), item.getPageserial(), item.getBookId(), item.getOwnerNo(), item.getSectionNo(),item.getPageNumber()
                                , item.getWidth(), item.getHeight(), item.getPictureUrl(), item.getSubjectCode(), item.getStatus()
                                , item.getExamName(), item.getAssistantName(), item.getSubjectName(), item.getBookName(), item.getExamId()
                                , isMore, pictureMore.startX_L, pictureMore.startY_L, pictureMore.endX_L, pictureMore.endY_L
                                , pictureMore.startX_R, pictureMore.startY_R, pictureMore.endX_R, pictureMore.endY_R
                                , ComUtil.getStringDate(), null, null, 1, false
                                ,item.getExamPageNumber(), item.getExamPageNo(), item.getIsAnswerSheet(), item.getSourceType()));
                for(StudentExamGridInfoResp_grids item2 : item.getGrids()) {
                    //插入格子信息
                    DBUtils.getInstance(this.getActivity()).insertPenOffLineGridInfoChild(new PenOffLineGridInfoChild(null, item2.getGridId(), item2.getGridType(), item2.getPageserial()
                            , item2.getBookId(), item2.getPageNumber(), item2.getSectionNo(), item2.getOwnerNo(), item2.getPageNum()
                            , item2.getKnowledgeMapOutlineContentId(), item2.getContentType(), item2.getExamId(), item2.getExamName()
                            , item2.getIsExam(), item2.getQuestionId(), item2.getQuestion(), item2.getQuestionAnswer(), item2.getFileName()
                            , item2.getTotalPages(), item2.getDuration(), item2.getSetContent(), item2.getStartX(), item2.getStartY(), item2.getEndX(), item2.getEndY()
                            , item2.getClassId(), item2.getSourceNodeId(), item2.getSpreadFlag(), item2.getBigPicWidth(), item2.getBigPicHeight(), item2.getQuestionTypeId(), penOffLineGridInfoId));
                }
            } else {
                //比较页信息
                if(ComparePenOffLinePage.comparePage(item, info)){

                } else {
                    //如果页信息更新了，数据库更新
                    LogUtils.e("上次的是旧数据，更新了数据，重新入库");
                    info.setExamPageNumber(item.getExamPageNumber());
                    info.setExamPageNo(item.getExamPageNo());
                    info.setIsAnswerSheet(item.getIsAnswerSheet());
                    info.setSourceType(item.getSourceType());
                    info.setExamId(item.getExamId());
                    info.setExamName(item.getExamName());
                    info.setAssistantName(item.getAssistantName());
                    info.setBookName(item.getBookName());
                    DBUtils.getInstance(this.getActivity()).updatePenOffLineGridInfo(info);
                }
                if(info.getGrids() == null || info.getGrids().size() == 0) {
                    //如果是旧数据，需要插入格子信息
                    LogUtils.e("上次的是旧数据，插入格子信息");
                    for(StudentExamGridInfoResp_grids item2 : item.getGrids()) {
                        DBUtils.getInstance(this.getActivity()).insertPenOffLineGridInfoChild(new PenOffLineGridInfoChild(null, item2.getGridId(), item2.getGridType(), item2.getPageserial()
                                , item2.getBookId(), item2.getPageNumber(), item2.getSectionNo(), item2.getOwnerNo(), item2.getPageNum()
                                , item2.getKnowledgeMapOutlineContentId(), item2.getContentType(), item2.getExamId(), item2.getExamName()
                                , item2.getIsExam(), item2.getQuestionId(), item2.getQuestion(), item2.getQuestionAnswer(), item2.getFileName()
                                , item2.getTotalPages(), item2.getDuration(), item2.getSetContent(), item2.getStartX(), item2.getStartY(), item2.getEndX(), item2.getEndY()
                                , item2.getClassId(), item2.getSourceNodeId(), item2.getSpreadFlag(), item2.getBigPicWidth(), item2.getBigPicHeight(), item2.getQuestionTypeId(), info.getId()));
                    }
                } else {
                    //如果格子数据更新了，需要重新更新数据
                    if(ComparePenOffLinePage.comparePageGird(info.getGrids(), item.getGrids())) {

                    } else {
                        //后台数据跟本地数据库数据不相等，删除本地数据，重新插入
                        LogUtils.e("后台数据跟本地数据库数据不相等，删除本地数据，重新插入");
                        for (PenOffLineGridInfoChild item_db : info.getGrids()) {
                            DBUtils.getInstance(this.getActivity()).deletePenOffLineGridInfoChild(item_db);
                        }
                        for (StudentExamGridInfoResp_grids item2 : item.getGrids()) {
                            DBUtils.getInstance(this.getActivity()).insertPenOffLineGridInfoChild(new PenOffLineGridInfoChild(null, item2.getGridId(), item2.getGridType(), item2.getPageserial()
                                    , item2.getBookId(), item2.getPageNumber(), item2.getSectionNo(), item2.getOwnerNo(), item2.getPageNum()
                                    , item2.getKnowledgeMapOutlineContentId(), item2.getContentType(), item2.getExamId(), item2.getExamName()
                                    , item2.getIsExam(), item2.getQuestionId(), item2.getQuestion(), item2.getQuestionAnswer(), item2.getFileName()
                                    , item2.getTotalPages(), item2.getDuration(), item2.getSetContent(), item2.getStartX(), item2.getStartY(), item2.getEndX(), item2.getEndY()
                                    , item2.getClassId(), item2.getSourceNodeId(), item2.getSpreadFlag(), item2.getBigPicWidth(), item2.getBigPicHeight(), item2.getQuestionTypeId(), info.getId()));
                        }

                    }
                }
            }
        }
    }

    private void setRealtimeMode() {
        mOffLineDots.clear();
        mOffLineReq.getGridInfoListVo().clear();
        BlePenStreamManager.getInstance().setRealtimeMode();
    }

    private void downLoadImg() {
        mPic_w = mCurGrid.getWidth().intValue();
        mPic_h = mCurGrid.getHeight().intValue();
        mDoodle_b = null;
        mDoodle_f = null;
        mIsLoadImg_b_end = false;
        mIsLoadImg_f_end = false;

        mPicFilePath_b = FileUtils.getPicFilePath(this.getActivity(), "offline" + File.separator + "b", "" + mCurGrid.getPicId(), "");
        mPicFilePath_f = FileUtils.getPicFilePath(this.getActivity(), "offline" + File.separator + "f", "" + mCurGrid.getPicId(), "");
        mPicFilePath_c = FileUtils.getPicFilePath(this.getActivity(), "offline" + File.separator + "c", "" + mCurGrid.getPicId(), "");


        LogUtils.i("m2: mPicFilePath_b = " + mPicFilePath_b);
        LogUtils.i("m2: mPicFilePath_f = " + mPicFilePath_f);
        LogUtils.i("m2: mPicFilePath_c = " + mPicFilePath_c);

        String url_b;
        File file_b = new File(mPicFilePath_b);
        File file_c = new File(mPicFilePath_c);

        if(file_c.exists()) {
            url_b = mPicFilePath_c;
        }  else if(file_b.exists()) {
            url_b = mPicFilePath_b;
        } else {
            url_b = mCurGrid.getPictureUrl();
        }



        final String url_b_temp = url_b;

		mDoodle_b = null;
        mDoodle_f = null;
        fl_doodle.removeAllViews();
        mGraffitiView = null;
        mGraffitiTouchGestureListener = null;
		
        Glide.with(this).asBitmap().load(url_b_temp).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(new CustomTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                        LogUtils.e("m1:Glde图片-成功  = " + url_b_temp + ", threadName = " + Thread.currentThread().getName());
                        mDoodle_b = resource;
                        mIsLoadImg_b_end = true;
                        if(url_b_temp.equals(mCurGrid.getPictureUrl())) {
                            //从网上下载，需要存在本地
                            String path_b = mPicFilePath_b;
                            Observable.create(new ObservableOnSubscribe<Integer>() {
                                @Override
                                public void subscribe(final ObservableEmitter<Integer> emitter) throws Exception {
                                    LogUtils.i("========================= subscribe currentThread name: " + Thread.currentThread().getName());
                                    FileUtils.saveBitmap(resource, path_b);
                                    emitter.onNext(1);
                                    emitter.onComplete();

                                }
                            }).subscribeOn(Schedulers.newThread())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Observer<Integer>() {
                                        @Override
                                        public void onSubscribe(Disposable d) {
                                            //创建只运行1次，执行顺序1 -- main
                                            LogUtils.i("========================= onSubscribe currentThread name: " + Thread.currentThread().getName());

                                        }

                                        @Override
                                        public void onNext(Integer o) {
                                            //运行多次 执行顺序3 -- thread
                                            LogUtils.i("========================= onNext currentThread name: " + Thread.currentThread().getName());
                                            //initDoodleData_pre();
                                            downLoadImg_f();
                                        }

                                        @Override
                                        public void onError(Throwable e) {
                                            //运行1次  -- thread
                                            LogUtils.i("========================= onError currentThread name: " + Thread.currentThread().getName() + "--" + e.getMessage());

                                        }

                                        @Override
                                        public void onComplete() {
                                            //运行1次  -- thread
                                            LogUtils.i("========================= onComplete currentThread name: " + Thread.currentThread().getName());

                                        }
                                    });
                        } else {
                            downLoadImg_f();
                        }
                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        super.onLoadFailed(errorDrawable);
                        LogUtils.e("m1:Glde图片-失败  = " + url_b_temp + ", threadName = " + Thread.currentThread().getName());
                        //图片已经损坏要处理
                        if(url_b_temp.equals(mPicFilePath_b)) {
                            LogUtils.e("图片有问题，删除这一张图片：" + mPicFilePath_b);
                            file_b.delete();
                            downLoadImg();
                        } else if(url_b_temp.equals(mPicFilePath_c)) {
                            LogUtils.e("图片有问题，删除这一张图片：" + mPicFilePath_c);
                            file_c.delete();
                            downLoadImg();
                        } else {
                            mIsLoadImg_b_end = true;
                            //initDoodleData_pre();
                            downLoadImg_f();
                        }
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }
                });




    }

    private void downLoadImg_f() {
        File file_f = new File(mPicFilePath_f);
        if(file_f.exists()) {
            Glide.with(this).asBitmap().load(mPicFilePath_f).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(new CustomTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            LogUtils.e("m1:Glde图片-成功  = " + mPicFilePath_f + ", threadName = " + Thread.currentThread().getName());
                            mDoodle_f = resource;
                            mIsLoadImg_f_end = true;
                            initDoodleData_pre();
                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            super.onLoadFailed(errorDrawable);
                            LogUtils.e("m1:Glde图片-失败  = " + mPicFilePath_f + ", threadName = " + Thread.currentThread().getName());
                            LogUtils.e("图片有问题，删除这一张图片：" + mPicFilePath_f);
                            file_f.delete();
                            downLoadImg_f();
                            /*mIsLoadImg_f_end = true;
                            initDoodleData_pre();*/
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {

                        }
                    });
        } else {
            mDoodle_f = resizeImage(mSmall_bitmap, mCurGrid.getWidth().intValue(), mCurGrid.getHeight().intValue());
            mIsLoadImg_f_end = true;
            initDoodleData_pre();
        }
    }

    public Bitmap resizeImage(Bitmap bitmap, int width, int height) {

        int bmpWidth = bitmap.getWidth();
        int bmpHeight = bitmap.getHeight();

        float scaleWidth = ((float) width) / bmpWidth;
        float scaleHeight = ((float) height) / bmpHeight;

        LogUtils.i("m1:宽放大倍数：" + scaleWidth +  ", bmpWidth = " + bmpWidth + ", width = " + width);
        LogUtils.i("m1:高放大倍数：" + scaleHeight);

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);

        return Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
    }

    private void initDoodleData_pre() {
        if(mIsLoadImg_b_end && mIsLoadImg_f_end) {
            if(mDoodle_b == null && mDoodle_f == null) {
                LogUtils.e("出错了，背景图为null");
                if(DialogXUtil.isShowProgressDialog()) {
                    DialogXUtil.hideProgressDialog();
                    if(mListener != null) {
                        mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
                    }
                }
            } else {
                if(mDoodle_b == null) {
                    //在弱网情况下，用透明图片代替背景图片
                    mDoodle_b = mDoodle_f;
                }
                initGraffitiData();
            }
        }
    }


    private void setSupportDoodle(boolean isSupport) {
        if (mGraffitiTouchGestureListener != null) {
            mGraffitiTouchGestureListener.setSupportGraffiti(isSupport);
        }
    }

    private void setSupportTrans(boolean isSupport) {
        if (mGraffitiTouchGestureListener != null) {
            mGraffitiTouchGestureListener.setSupportTrans(isSupport);
        }
    }

    private void initGraffitiData() {
        fl_doodle.removeAllViews();
        if(mCurGrid_isMore_endnull != null && mCurDot != null) {
            Date currentTime = new Date(mCurDot.timeLong);
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = formatter.format(currentTime);
            mCurGrid_isMore_endnull.setBeginTime(dateString);
            LogUtils.i("处理开始时间： 笔的时间：" + mCurDot.timeLong + ", 时间字符串： " + dateString);
        }
        mGraffitiView = new GraffitiView(this.getActivity(), mDoodle_b, mDoodle_f, false, false, new GraffitiView.IGraffitiViewListener(){

            @Override
            public void onSaved(List<Bitmap> bitmaps) {
                LogUtils.i("m1:涂鸦保存成功"  + ", threadName = " + Thread.currentThread().getName());
                String path_c = mPicFilePath_c;
                String path_f = mPicFilePath_f;
                if(mCurGrid_isMore_endnull != null /*&& mCurGrid_isMore_endnull.getIsMore()*/ && !mCurGrid_isMore_endnull.getIsWrite()) {
                    mCurGrid_isMore_endnull.setIsWrite(true);
                    DBUtils.getInstance(PenConnectFragment.this.getActivity()).updatePenOffLineGridInfo(mCurGrid_isMore_endnull);
                }
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(final ObservableEmitter<Integer> emitter) throws Exception {
                        LogUtils.i("========================= subscribe currentThread name: " + Thread.currentThread().getName());
                        FileUtils.saveBitmap(bitmaps.get(0), path_c);
                        FileUtils.saveBitmap(bitmaps.get(1), path_f);
                        emitter.onNext(1);
                        emitter.onComplete();

                    }
                }).subscribeOn(Schedulers.newThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<Integer>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                //创建只运行1次，执行顺序1 -- main
                                LogUtils.i("========================= onSubscribe currentThread name: " + Thread.currentThread().getName());

                            }

                            @Override
                            public void onNext(Integer o) {
                                //运行多次 执行顺序3 -- thread
                                LogUtils.i("========================= onNext currentThread name: " + Thread.currentThread().getName());
                                if(mOffLineDots.isEmpty()) {
                                    if(DialogXUtil.isShowProgressDialog()) {
                                        DialogXUtil.hideProgressDialog();
                                        if(mListener != null) {
                                            mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
                                        }
                                    }
                                    if(mListener != null) {
                                        mListener.on_ct_switchTab();
                                    }
                                } else {
                                    changePic();
                                }
                            }

                            @Override
                            public void onError(Throwable e) {
                                //运行1次  -- thread
                                LogUtils.i("========================= onError currentThread name: " + Thread.currentThread().getName() + "--" + e.getMessage());

                            }

                            @Override
                            public void onComplete() {
                                //运行1次  -- thread
                                LogUtils.i("========================= onComplete currentThread name: " + Thread.currentThread().getName());

                            }
                        });
            }
        });
        mGraffitiTouchGestureListener = new GraffitiOnTouchGestureListener(mGraffitiView, new GraffitiOnTouchGestureListener.IGraffitiOnTouchGestureListener() {
            @Override
            public void onTest() {

            }
            @Override
            public void onCallScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                LogUtils.i("m1:滚动手指：distanceX: " + distanceX + ", distanceY:" + distanceY);
            }
        });

        IGraffitiTouchDetector detector = new GraffitiTouchDetector(this.getActivity(), mGraffitiTouchGestureListener);
        mGraffitiView.setDefaultTouchDetector(detector);


        mGraffitiTouchGestureListener.setSupportScale(false); //禁止放大缩小
        setSupportDoodle(false);
        setSupportTrans(false);
        mGraffitiTouchGestureListener.setTouchType(GraffitiOnTouchGestureListener.TOUCH_TYPE_ALL);


        //mGraffitiView.setStartXy(true);
        mGraffitiView.setColor(Color.BLACK);
        mGraffitiView.setIsDrawableOutside(false);
        mGraffitiView.setSize(4);
        fl_doodle.addView(mGraffitiView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        delayToDot(300);

    }

    private void delayToDot(int time) {
        mCurDotNum = 0;
        Observable.timer(time, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer< Long >() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        LogUtils.d("m1:onNext " + aLong + ", threadName = " + Thread.currentThread().getName());
                        do {
                            drawTrack_real(mCurDot);
                        } while(isOkPoll());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    private boolean isOkPoll() {
        if(mOffLineDots.isEmpty()) {
            if(DialogXUtil.isShowProgressDialog()) {
                //DialogXUtil.hideProgressDialog();
                if(mListener != null) {
                    mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
                }
            }
            if (mGraffitiView != null) {
                mGraffitiView.save();
            }
            return false;
        }
        CoordinateInfo prev = mCurDot;
        mCurDot = mOffLineDots.poll();
        DialogXUtil.progressDialogSetCur(mCurDot.offLineDateCurrentSize * 100 / mCurDot.offLineDataAllSize);
        if(prev.pageAddress.equals(mCurDot.pageAddress)) {
            if(mCurGrid.getSourceType() == PageSourceType.JIAOFU) {
                if(mCurGrid.getIsMore()) {
                    //每次都要判断，点击的区域是否需要换页
                    if(!choicePagePictrue(mCurGrid)) {
                        LogUtils.e("m1----多页条件符合，需要切换页isOkPoll()");
                        //需要切换图片
                        mCurDotNum = 0;

                        if (mGraffitiView != null) {
                            mGraffitiView.save();
                        }

                        return false;
                    } else {
                        //LogUtils.e("m1----多页条件符合，不需要切换页isOkPoll()，还是原来的页面");
                        mCurDotNum++;
                        if(mCurDotNum > mMaxDotNum) {
                            //重新切线程
                            delayToDot(30);
                            return false;
                        } else if(mCurDotNum > mMinDotNum && mCurDot.state == TsdService.PEN_DOWN_MESSAGE) {
                            //重新切换线程
                            delayToDot(30);
                            return false;
                        }
                        return true;
                    }
                } else {
                    mCurDotNum++;
                    if(mCurDotNum > mMaxDotNum) {
                        //重新切线程
                        delayToDot(30);
                        return false;
                    } else if(mCurDotNum > mMinDotNum && mCurDot.state == TsdService.PEN_DOWN_MESSAGE) {
                        //重新切换线程
                        delayToDot(30);
                        return false;
                    }
                    return true;
                }
            } else if (mCurGrid.getSourceType() == PageSourceType.TUPU) {
                int type = 0; //1: 在当前图片，2：在需要切图片，3：没有点击到图谱找那个的训练
                for(PenOffLineGridInfoChild child : mCurGrid.getGrids()) {
                    if(child.getContentType() == GridSourceContentType.DOT_TRAIN
                            && choicePagePictrueChild(child)) {
                        type = 1;
                        break;
                    }
                }

                if(type != 1) {
                    LogUtils.e("m1----多页条件符合，需要切换页isOkPoll()");
                    //需要切换图片
                    mCurDotNum = 0;

                    if (mGraffitiView != null) {
                        mGraffitiView.save();
                    }

                    return false;
                } else {
                    //LogUtils.e("m1----多页条件符合，不需要切换页isOkPoll()，还是原来的页面");
                    mCurDotNum++;
                    if(mCurDotNum > mMaxDotNum) {
                        //重新切线程
                        delayToDot(30);
                        return false;
                    } else if(mCurDotNum > mMinDotNum && mCurDot.state == TsdService.PEN_DOWN_MESSAGE) {
                        //重新切换线程
                        delayToDot(30);
                        return false;
                    }
                    return true;
                }

            } else {
                LogUtils.e("数据不符合要求，既不是图谱，也不是教辅");
                delayToDot(30);
                return false;
            }

        } else {
            //需要切换图片
            mCurDotNum = 0;

            if (mGraffitiView != null) {
                mGraffitiView.save();
            }

            return false;
        }
    }

    private void changePic() {
        if(mCurDot == null) {
            if (mGraffitiView != null) {
                mGraffitiView.save();
            } else {
                DialogXUtil.hideProgressDialog();
                if(mListener != null) {
                    mListener.on_ct_setmMoudle(TsdService.MODULE_DEFAULT);
                }
            }
            return;
        }
        mCurGrid = null;
        List<PenOffLineGridInfo> mCurGridList = DBUtils.getInstance(this.getActivity()).getPenOffLineGridInfoByPageserial(mCurDot.pageAddress);
        if(mCurGridList != null && mCurGridList.size() > 0) {
            for(PenOffLineGridInfo item : mCurGridList) {
                if(item.getSourceType() == PageSourceType.JIAOFU) {
                    if(item.getIsMore()) {
                        //多页符合条件
                        if(choicePagePictrue(item)) {
                            LogUtils.e("m1----多页条件符合，需要切换页changePic()");
                            mCurGrid = item;
                            mCurGrid_isMore_endnull = item;
                            break;
                        }
                    } else {
                        mCurGrid = item;
                        mCurGrid_isMore_endnull = item;
                        break;
                    }
                } else if(item.getSourceType() == PageSourceType.TUPU){
                    //判断点击的是否是图谱中的点阵训练
                    for(PenOffLineGridInfoChild child : item.getGrids()) {
                        if(child.getContentType() == GridSourceContentType.DOT_TRAIN
                                && choicePagePictrueChild(child)) {
                            mCurGrid = item;
                            mCurGrid_isMore_endnull = item;
                            break;
                        }
                    }
                    if(mCurGrid != null) {
                        break;
                    }
                } else {
                    LogUtils.e("数据有问题，既不是图谱，也不是教辅");
                }

            }
        }
        if(mCurGrid != null) {
            downLoadImg();
        } else {
            //没有找到这样的页，那么删除点，直到按下的点
            Observable.create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(final ObservableEmitter<Integer> emitter) throws Exception {
                    LogUtils.i("========================= subscribe currentThread name: " + Thread.currentThread().getName());
                    if(mCurDot != null) {
                        String badAddress = mCurDot.pageAddress;
                        mCurDot = mOffLineDots.poll();
                        if(mCurDot != null && badAddress.equals(mCurDot.pageAddress) && mCurDot.state != TsdService.PEN_DOWN_MESSAGE) {
                            mCurDot = mOffLineDots.poll();
                        }
                        while(mCurDot !=null && mCurDot.state != TsdService.PEN_DOWN_MESSAGE){
                            mCurDot = mOffLineDots.poll();
                        }
                    }

                    emitter.onNext(1);
                    emitter.onComplete();

                }
            }).subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Integer>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            //创建只运行1次，执行顺序1 -- main
                            LogUtils.i("========================= onSubscribe currentThread name: " + Thread.currentThread().getName());

                        }

                        @Override
                        public void onNext(Integer o) {
                            //运行多次 执行顺序3 -- thread
                            LogUtils.i("========================= onNext currentThread name: " + Thread.currentThread().getName());
                            //都要下面操作，mCurDot == null时，下面错误会取消进度框
                            changePic();
                        }

                        @Override
                        public void onError(Throwable e) {
                            //运行1次  -- thread
                            LogUtils.i("========================= onError currentThread name: " + Thread.currentThread().getName() + "--" + e.getMessage());

                        }

                        @Override
                        public void onComplete() {
                            //运行1次  -- thread
                            LogUtils.i("========================= onComplete currentThread name: " + Thread.currentThread().getName());

                        }
                    });
            LogUtils.e("没有找到格子");
        }
    }

    private boolean choicePagePictrue(PenOffLineGridInfo info) {
        float x = TsdPenUtil.getRealX(mCurDot.coordX, info.getWidth());
        float y = TsdPenUtil.getRealY(mCurDot.coordY, info.getHeight());
        if(x > info.getStartX_L().floatValue() && x < info.getEndX_L().floatValue() && y > info.getStartY_L().floatValue() && y < info.getEndY_L().floatValue()) {
            return  true;
        }
        if(x > info.getStartX_R().floatValue() && x < info.getEndX_R().floatValue() && y > info.getStartY_R().floatValue() && y < info.getEndY_R().floatValue()) {
            return  true;
        }
        return false;
    }

    private boolean choicePagePictrueChild(PenOffLineGridInfoChild info) {
        float x = TsdPenUtil.getRealX(mCurDot.coordX, info.getBigPicWidth());
        float y = TsdPenUtil.getRealY(mCurDot.coordY, info.getBigPicHeight());
        if(x > info.getStartX().floatValue() && x < info.getEndX().floatValue() && y > info.getStartY().floatValue() && y < info.getEndY().floatValue()) {
            return  true;
        }
        return false;
    }

    private void drawTrack_real(CoordinateInfo dot) {
        mTemp_x = TsdPenUtil.getRealX(dot.coordX, mPic_w);
        mTemp_y = TsdPenUtil.getRealY(dot.coordY, mPic_h);

        if (dot.state == TsdService.PEN_DOWN_MESSAGE) {
            mGraffitiTouchGestureListener.r_onDown(mTemp_x, mTemp_y);
            mGraffitiTouchGestureListener.r_onScrollBegin(mTemp_x, mTemp_y);
        } else if (dot.state == TsdService.PEN_COODINAT_MESSAGE) {
            mGraffitiTouchGestureListener.r_onScroll(mTemp_x, mTemp_y);
        } else if (dot.state == TsdService.PEN_UP_MESSAGE) {
            mGraffitiTouchGestureListener.r_onScrollEnd(mTemp_x, mTemp_y);
        }

    }

    private void drawTrack_rxJava() {
        rxjava_disposable();

        Observable.interval(500, 1000, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.single())
                .subscribe(new Observer < Long > () {
                    @Override
                    public void onSubscribe(Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                BlePenStreamManager.getInstance().getPenInfo();
                            }
                        });
                        //}
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    private void rxjava_disposable() {
        if(disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
    }

    private void showSecondProgress(){

    }

//====================================================================================================================
    public void callErr(int code, String msg) {
        if(tv_err == null) {
            return;
        }
        if(code == TsdService.ERR_TSD_BT_OPEN_T) {
            //如果蓝牙打开成功，重新初始化
            tv_err.setVisibility(View.GONE);
            if(mListener != null) {
                //mListener.on_ct_rePenInit();
            }
        } else {
            tv_err.setVisibility(View.VISIBLE);
            tv_err.setText(msg);
            mErr_code = code;
        }
    }

    public void refreshScan(boolean isScaning) {
        if(isScaning && scanAnim != null) {
            iv_refresh.startAnimation(scanAnim);
            if(mPenMainListAdapter != null) {
                mPenMainListAdapter.clearDevice();
            }
        } else {
            if(iv_refresh != null) {
				iv_refresh.clearAnimation();
			}

        }
    }

    public void addDevice(BleDevice bleDevice) {
        if(mPenMainListAdapter != null) {
            mPenMainListAdapter.addDevice(bleDevice);

            String lastMack_2 = SPUtils.getInstance().getString(Constants.USER_PEN_MAC);
            if(!StringUtil.isEmpty(lastMack_2) && lastMack_2.equals(bleDevice.getMac())) {
                //mListener.on_ct_stopScan(); //取消扫码
                //这个账号上次连接的就是这个笔
                penConnect(bleDevice);
            }

        }
    }

    public void penConnectStatus(int code, BleDevice bleDevice) {
        if(code == TsdService.CONN_PEN_START) {
            //DialogXUtil.waitDialogShow("正在连接中...");
        } else if(code == TsdService.CONN_PEN_FAIL) {
            if(DialogXUtil.isWaitDialogShow() || true) {
                DialogXUtil.waitDialogDismiss();
            }
            //Toast.makeText(getActivity(), "蓝牙连接失败", Toast.LENGTH_LONG).show();
            refreshShowView(false);
        } else if(code == TsdService.CONN_PEN_SUCCESS) {
            mStudentExamGridInfo = null;
            if(DialogXUtil.isWaitDialogShow()  || true) {
                DialogXUtil.waitDialogDismiss();
            }
            if(mPenMainListAdapter != null) {
                mPenMainListAdapter.setmLastDevMac(bleDevice.getMac());
            }
            refreshShowView(true);

            tv_pen_mac.setText("MAC:" + bleDevice.getMac());

            //BlePenStreamManager.getInstance().getPenInfo();


            String lastMack_2 = SPUtils.getInstance().getString(Constants.USER_PEN_MAC);
            String studentId = SPUtils.getInstance().getString(Constants.USER_ID_KEY);
            if(!bleDevice.getMac().equals(lastMack_2)) {
                //只有不更新新的笔时，才更新后台
                getPresenter().studentConfirmConnect(ComUtil.getHashmapByStr(
                        new String[]{"penMac", "penType", "studentId"},
                        new String[]{bleDevice.getMac(), "2", studentId})
                        , false, false, bleDevice);
            }

            setRealtimeMode();
        } else if(code == TsdService.CONN_PEN_DIS) {
            if(DialogXUtil.isWaitDialogShow() || true) {
                DialogXUtil.waitDialogDismiss();
            }
            refreshShowView(false);
        }
    }
    public void getPenInfo(int batteryPercent, int memoryPercent, int memoryByteNum) {
        tv_pen_dianliang.setText(batteryPercent + "%");
        tv_pen_dianliang.setTextColor(Color.parseColor("#00A8B2"));
        if(batteryPercent < 20) {
            iv_pen_dianliang.setImageResource(R.drawable.pen_dianliang_20);
            tv_pen_dianliang.setTextColor(Color.parseColor("#FF4A55"));
        } else if(batteryPercent < 40) {
            iv_pen_dianliang.setImageResource(R.drawable.pen_dianliang_40);
        } else if(batteryPercent < 60) {
            iv_pen_dianliang.setImageResource(R.drawable.pen_dianliang_60);
        } else if(batteryPercent < 80) {
            iv_pen_dianliang.setImageResource(R.drawable.pen_dianliang_80);
        } else {
            iv_pen_dianliang.setImageResource(R.drawable.pen_dianliang_100);
        }

        mMemoryByteNum = memoryByteNum;
        if(mListener != null && mListener.on_ct_getmMoudle() == TsdService.MODULE_PEN_OFFLINE) {
            if(mMemoryByteNum == 0 && mStudentExamGridInfo == null) {
                rxjava_disposable();
                DialogXUtil.progressDialogSetStyle("绘制新数据", "正在绘制数据，请勿断开蓝牙连接，上传过程中书写无效！", 2);
                DialogXUtil.progressDialogSetCur(0);
                String json = JsonUtils.toJson(mOffLineReq);
                LogUtils.i(json);
                getPresenter().studentExamGridInfo(json
                        , false, false);
            }
        }
    }

    //按下和弹起xy坐标都是错误的，都转成移动坐标, 还需要处理，按下弹起两个坐标都是0中间没有移动的情况。
    public void onCoordDraw(CoordinateInfo coordinateInfo) {
        if(coordinateInfo.isOFFLine) {
            mOffLineDots.offer(coordinateInfo);

            if(coordinateInfo.state == TsdService.PEN_DOWN_MESSAGE
                    && !mOffLineReq.getGridInfoListVo().contains(new StudentExamGridInfoReq_vo(coordinateInfo.pageAddress))) {
                mOffLineReq.getGridInfoListVo().add(new StudentExamGridInfoReq_vo(coordinateInfo.pageAddress));
            }
            if(DialogXUtil.isShowProgressDialog()) {
                DialogXUtil.progressDialogSetCur(coordinateInfo.offLineDateCurrentSize * 100 / coordinateInfo.offLineDataAllSize);
                /*if(coordinateInfo.offLineDateCurrentSize == coordinateInfo.offLineDataAllSize) {
                    DialogXUtil.progressDialogSetStyle("绘制新数据", "正在绘制数据，请勿断开蓝牙连接，上传过程中书写无效！", 2);
                    DialogXUtil.progressDialogSetCur(0);
                    String json = JsonUtils.toJson(mOffLineReq);
                    LogUtils.i(json);
                    getPresenter().studentExamGridInfo(json
                            , false, false);
                }*/

            } else {
                DialogXUtil.progressDialog();
                DialogXUtil.progressDialogSetStyle("上传新数据", "正在上传数据，请勿断开蓝牙连接，上传过程中书写无效！", 1);
                DialogXUtil.progressDialogSetCur(0);
                if(mListener != null) {
                    mListener.on_ct_setmMoudle(TsdService.MODULE_PEN_OFFLINE);
                    drawTrack_rxJava();
                }

            }
        }
    }

    public interface OnFragmentInteractionListener {
        void on_ct_rePenInit();
        boolean on_ct_isScaning();
        void on_ct_startScan();
        void on_ct_stopScan();
        void on_ct_finishPre();
        void on_ct_penConnect(BleDevice bleDevice);
        BleDevice on_ct_getmBleDevice();
        void on_ct_switchTab();
        void on_ct_setmMoudle(int module);
        int on_ct_getmMoudle();
        void on_ct_setIsConnect(boolean isConnect);
    }
}
